using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace ScottLane.VideoInbox
{
    /// <summary>
    /// Supports the writing of Windows Media Player wvx playlist files.
    /// </summary>
    public class WvxFile
    {
        private static readonly string titleElement = "Title";
        private static readonly string entryElement = "Entry";
        private static readonly string refElement = "Ref";
        private static readonly string hrefAttribute = "href";

        #region Constructor

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mediaFileName"></param>
        public WvxFile(string mediaFileName)
        {
            _mediaFileName = mediaFileName;
            _title = string.Empty;
            _entries = new List<string>();
        }

        #endregion

        #region Properties

        private string _mediaFileName;

        /// <summary>
        /// Gets the media file name.
        /// </summary>
        public string MediaFileName
        {
            get { return _mediaFileName; }
        }

        /// <summary>
        /// Gets the manifest file name.
        /// </summary>
        public string FileName
        {
            get { return GetFileName(_mediaFileName); }
        }

        private string _title;

        /// <summary>
        /// Gets or sets the file title.
        /// </summary>
        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }

        private List<string> _entries;

        /// <summary>
        /// Gets or sets the file entries.
        /// </summary>
        public List<string> Entries
        {
            get { return _entries; }
            set { _entries = value; }
        }

        #endregion

        //public static WvxFile FromPlaylist(Playlist playlist, DownloadStatus status)
        //{
        //    //WvxFile file = new WvxFile(playlist.DownloadFileName);
        //    //file.Title = video.Title;

        //    //ConfigurationSettings settings = ConfigurationSettings.Instance;

        //    //switch (status)
        //    //{
        //    //    case DownloadStatus.NotDownloaded:
        //    //        file.Entries.Add(settings.NotDownloadedVideoFileName);
        //    //        break;
        //    //    case DownloadStatus.Downloading:
        //    //        file.Entries.Add(settings.DownloadingVideoFileName);
        //    //        break;
        //    //    case DownloadStatus.Downloaded:
        //    //        file.Entries.Add(video.DownloadFileName);
        //    //        break;
        //    //}

        //    return null;
        //}

        /// <summary>
        /// Gets the wvx file name from the specified media file name.
        /// </summary>
        /// <param name="mediaFileName">The media file name.</param>
        /// <returns>The wvx file name.</returns>
        public static string GetFileName(string mediaFileName)
        {
            return Path.ChangeExtension(mediaFileName, ".wvx");
        }

        /// <summary>
        /// Loads a wvx file for a media file.
        /// </summary>
        /// <param name="mediaFileName">The media file name.</param>
        /// <returns>A WvxFile instance.</returns>
        public static WvxFile Load(string mediaFileName)
        {
            WvxFile wvx = new WvxFile(mediaFileName);

            using (XmlReader reader = XmlReader.Create(wvx.FileName))
            {
                reader.ReadStartElement();
                reader.ReadToFollowing(titleElement);
                wvx.Title = reader.ReadString();

                while (reader.ReadToFollowing(entryElement))
                {
                    reader.ReadToFollowing(refElement);
                    reader.MoveToAttribute(hrefAttribute);
                    wvx.Entries.Add(reader.ReadString());
                }
            }

            return wvx;
        }

        /// <summary>
        /// Writes the wvx file to disk. 
        /// </summary>
        public void Create()
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;

            using (XmlWriter writer = XmlTextWriter.Create(FileName, settings))
            {
                writer.WriteStartElement("ASX");
                writer.WriteStartAttribute("version");
                writer.WriteValue("3.0");
                writer.WriteEndAttribute();
                writer.WriteWhitespace(Environment.NewLine);
                writer.WriteStartElement(titleElement);
                writer.WriteValue(_title);
                writer.WriteEndElement();
                writer.WriteWhitespace(Environment.NewLine);

                foreach (string href in _entries)
                {
                    writer.WriteStartElement(entryElement);
                    writer.WriteWhitespace(Environment.NewLine);
                    writer.WriteStartElement(refElement);
                    writer.WriteStartAttribute(hrefAttribute);
                    writer.WriteValue(href);
                    writer.WriteEndAttribute();
                    writer.WriteEndElement();
                    writer.WriteWhitespace(Environment.NewLine);
                    writer.WriteEndElement();
                    writer.WriteWhitespace(Environment.NewLine);
                }

                writer.WriteEndElement();
            }

            // todo - creation date
            //wvxFile.CreationTime = video.Created;
        }

        /// <summary>
        /// Saves the wvx file.
        /// </summary>
        public void Save()
        {
            Delete();
            Create();
        }

        /// <summary>
        /// Deletes the wvx file.
        /// </summary>
        public void Delete()
        {
            if (File.Exists(FileName))
            {
                File.Delete(FileName);
            }
        }
    }
}
